下拉刷新 xPullRefresh
预览
介绍
常用下拉容器,不要虚拟切片。pulldown / refresh 用 Promise,组件自己收 refresher。listType 切换 scroll-view / list-view。#top / #sticky 和内容同一层滚动容器。不要原生子协商。scroll-view:App / Web #sticky 到达后 fixed,小程序 using-sticky。list-view:吸顶与 scroll-view 同一套逻辑,不要 sticky-section,App / Web hold + fixed,小程序 sticky。
平台兼容
| Harmony | H5 | andriod | IOS | 小程序 | UTS | UNIAPP-X SDK | version |
|---|---|---|---|---|---|---|---|
| ☑ | ☑ | ☑️ | ☑️ | ☑️ | ☑️ | 4.76+ | 1.1.18 |
文件路径
ts
@/uni_modules/tmx-ui/components/x-pull-refresh/x-pull-refresh.uvue使用
ts
<x-pull-refresh></x-pull-refresh>Props 属性
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| height | `` | string | "100%" |
| full | `` | boolean | true |
| empty | `` | boolean | false |
| listType | `` | string | "scroll-view" |
| refresh | `` | xPullRefreshFun | () : xPullRefreshFun => { return null } |
| pulldown | `` | xPullRefreshFun | () : xPullRefreshFun => { return null } |
| showScrollbar | `` | boolean | false |
Events 事件
| 名称 | 参数 | 说明 |
|---|---|---|
| scroll | - | - |
| refresh | - | - |
| pulldown | - | - |
Slots 插槽
| 名称 | 说明 | 数据 |
|---|---|---|
| top | - | - |
| sticky | - | - |
| empty | - | - |
| default | - | - |
| refresh | - | - |
Ref 方法
| 名称 | 参数 | 返回值 | 说明 |
|---|---|---|---|
| refreshSize | - | - | - |
| resetScroll | - | - | - |
| setScrollTop | - | - | - |
示例文件路径
json
/pages/fankui/pull-refresh示例源码
uvue
vue
<template>
<!-- #ifdef MP-WEIXIN -->
<page-meta :page-style="`background-color:${xThemeConfigBgColor}`">
<navigation-bar :background-color="xThemeConfigNavBgColor"
:front-color="xThemeConfigNavFontColor"></navigation-bar>
</page-meta>
<!-- #endif -->
<view class="page">
<x-pull-refresh class="pageList" height="100%" :list-type="listType" :empty="list.length == 0"
:pulldown="onPulldown" :refresh="onLoadMore">
<template #top>
<x-sheet :margin="[0, 0, 0, 8]">
<x-text font-size="18" class=" text-weight-b mb-8">下拉刷新 xPullRefresh</x-text>
<x-text color="#999999" class="mb-12">常用下拉容器。向下先推顶部,菜单吸顶后再滚内容。下拉和触底都交 Promise。listType 可切
scroll-view / list-view。本页 {{ list.length }} 条,当前 {{ listType }}。</x-text>
<view class="flex flex-row flex-row-center-between">
<x-button size="small" class="flex-1" @click="toggleListType">容器</x-button>
<x-button size="small" class="ml-5 flex-1" @click="reloadAll">重载</x-button>
<x-button size="small" class="ml-5 flex-1" @click="appendRows">追加</x-button>
<x-button size="small" class="ml-5 flex-1" @click="clearAll">清空</x-button>
</view>
</x-sheet>
</template>
<template #sticky="{ pinned }">
<view >
<x-tabs v-model="menuId" :list="tabList" item-width="33.333%" height="44"></x-tabs>
</view>
</template>
<template v-if="listType == 'scroll-view'">
<view style="height: 8px;"></view>
<view v-for="item in list" :key="item.key" class="cardWrap">
<view class="card" :style="{ backgroundColor: cardBg }">
<x-text>{{ item.title }}</x-text>
</view>
</view>
</template>
<template v-else>
<list-item>
<view style="height: 8px;"></view>
</list-item>
<list-item v-for="item in list" :key="item.key">
<view class="cardWrap">
<view class="card" :style="{ backgroundColor: cardBg }">
<x-text>{{ item.title }}</x-text>
</view>
</view>
</list-item>
</template>
<template #empty>
<x-empty v-if="list.length == 0" :empty="true" :loading="false" btn-label="加载数据"
@click="reloadAll"></x-empty>
</template>
</x-pull-refresh>
</view>
</template>
<script lang="ts" setup>
import { computed, ref } from "vue"
import { xConfig, TABS_ITEM_INFO } from "@/uni_modules/tmx-ui"
type DemoRow = {
key : string
title : string
}
function makeRows(from : number, count : number) : DemoRow[] {
const out : DemoRow[] = []
for (let i = 0; i < count; i++) {
const n = from + i
out.push({
key: n.toString(),
title: "下拉刷新,上拉加载 - " + (n + 1).toString()
})
}
return out
}
const listType = ref<string>("scroll-view")
const menuId = ref<string>("all")
const tabList = [
{ id: "all", title: "综合" },
{ id: "new", title: "新品" },
{ id: "hot", title: "热门" }
] as TABS_ITEM_INFO[]
const list = ref<DemoRow[]>(makeRows(0, 12))
const cardBg = computed(() : string => {
if (xConfig.dark == "dark") return xConfig.sheetDarkColor
return "#ffffff"
})
function wait(ms : number) : Promise<void> {
return new Promise<void>((resolve) => {
setTimeout(() => {
resolve()
}, ms)
})
}
function toggleListType() : void {
if (listType.value == "list-view") {
listType.value = "scroll-view"
return
}
listType.value = "list-view"
}
function reloadAll() : void {
list.value = makeRows(0, 8)
}
function appendRows() : void {
list.value = list.value.concat(makeRows(list.value.length, 4))
}
function keepEight() : void {
list.value = list.value.slice(0, 8)
}
function clearAll() : void {
list.value = [] as DemoRow[]
}
async function onPulldown() : Promise<void> {
await wait(800)
list.value = makeRows(0, 8)
}
async function onLoadMore() : Promise<void> {
await wait(600)
appendRows()
}
</script>
<style scoped>
.page {
flex: 1;
display: flex;
flex-direction: column;
}
.pageList {
flex: 1;
min-height: 0;
}
.cardWrap {
padding: 0 8px 8px 8px;
}
.card {
height: 120px;
padding: 16px;
border-radius: 10px;
display: flex;
flex-direction: column;
justify-content: center;
}
</style>